#include <iostream>
#include <pthread.h>
#include <unistd.h>
using namespace std;
#define NUM 5
// 没有申请锁版本的购票
/* int tickets = 1000;
void *getTickets(void *args)
{
    while(true)
    {
        if(tickets>0)
        {
            usleep(1);
            tickets--;
            cout<<(char*)args<<" "<<"buy tickets success"<<"票还剩"<<tickets<<"张"<<endl;

        }
        else{
            break;
        }
    }
}

int main()
{
    pthread_t t1, t2, t3;
    pthread_create(&t1, nullptr, getTickets, (void *)"thread1");
    pthread_create(&t2, nullptr, getTickets, (void *)"thread2");
    pthread_create(&t3, nullptr, getTickets, (void *)"thread3");
    pthread_join(t1,nullptr);
     pthread_join(t2,nullptr);
      pthread_join(t3,nullptr);

    return 0;
}
 */
// 设置锁，全局
/* int tickets = 1000;
pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;//使用宏定义并初始化一个互斥锁
void *getTickets(void *args)
{
    while (true)
    {
        pthread_mutex_lock(&mtx);
        // 访问临界区之前加锁
        if (tickets > 0)
        {
            usleep(1);
            tickets--;
            cout << (char *)args << " "
                 << "buy tickets success"
                 << "票还剩" << tickets << "张" << endl;
            // 访问临界区完解锁
            pthread_mutex_unlock(&mtx);
        }
        else
        {
            // 处理最后一次tickets为0的情况，不会进入if条件判断，但之前申请加锁了，所以也要解锁
            pthread_mutex_unlock(&mtx);
            break;
        }
    }
}

int main()
{
    pthread_t t1, t2, t3;
    pthread_create(&t1, nullptr, getTickets, (void *)"thread1");
    pthread_create(&t2, nullptr, getTickets, (void *)"thread2");
    pthread_create(&t3, nullptr, getTickets, (void *)"thread3");
    pthread_join(t1, nullptr);
    pthread_join(t2, nullptr);
    pthread_join(t3, nullptr);

    return 0;
} */




//设置锁，局部
class threadData
{
    public:
    threadData(const string& name, pthread_mutex_t* mtx)
    :_name(name)
    ,_mtx(mtx)
    {

    }
    public:
    string _name;
    pthread_mutex_t* _mtx;

};
int tickets=1000;
void* getTickets(void* args)
{
 threadData* th=(threadData*)args;

    while(true)
    {
        pthread_mutex_lock(th->_mtx);//加锁
        if(tickets>0)
        {
            usleep(rand()%1000);//使产生的休眠时间随机
            tickets--;
            cout<<th->_name<<" "<<"tickets:"<<tickets<<endl;
            pthread_mutex_unlock(th->_mtx);//解锁
        }
        else
        {
            pthread_mutex_unlock(th->_mtx);//解锁
            break;
        }
        usleep(rand()%2000);
    }
    delete th;

}
int main()
{
    srand((unsigned long)time(nullptr)^getpid()^0x12);
    pthread_mutex_t mtx;//定义一个互斥锁
    pthread_mutex_init(&mtx,nullptr);//初始化
    pthread_t t[NUM];
    for(int i=0;i<NUM;i++)
    {
        string name="thread";
        name+=to_string(i+1);
        threadData* th=new threadData(name,&mtx);
        pthread_create(t+i,nullptr,getTickets,(void*)th);//创建线程

    }
    for(int i=0;i<NUM;i++)
    {
        pthread_join(t[i],nullptr);
    }
    pthread_mutex_destroy(&mtx);//销毁锁，释放资源
    return 0;
}

